package com.edu.cuotibook.service;

import com.alibaba.excel.EasyExcel;
import com.edu.cuotibook.common.NoModelDataListener;
import com.edu.cuotibook.dao.ExamPaperDaoService;
import com.edu.cuotibook.dao.ExaminationDaoService;
import com.edu.cuotibook.dao.ExcelDaoService;
import com.edu.cuotibook.dao.WrongAnswerDaoService;
import com.edu.cuotibook.entity.common.CodeMsg;
import com.edu.cuotibook.entity.common.CommonException;
import com.edu.cuotibook.entity.dto.ImageLengthDTO;
import com.edu.cuotibook.entity.pojo.ExamPaper;
import com.edu.cuotibook.entity.pojo.Examination;
import com.edu.cuotibook.entity.pojo.WrongAnswer;
import com.github.pagehelper.PageInfo;
import com.github.qrpcode.domain.PaperOut;
import com.github.qrpcode.domain.WordCore;
import com.github.qrpcode.domain.WordGo;
import com.github.qrpcode.domain.WordPaper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * create by sym  2021/3/24 20:31.
 * word加工厂  资源整合处
 */
@Service
public class GenerateService {

    @Autowired
    private ExcelDaoService excelDaoService;
    @Autowired
    ExaminationDaoService examinationDaoService;
    @Autowired
    ExamPaperDaoService examPaperDaoService;
    @Autowired
    WrongAnswerDaoService wrongAnswerDaoService;


    public  static ThreadLocal<String> homedirThreadLocal = new ThreadLocal<>();

    //显示路径
    public Examination getDirs(Long id){
        //从考试表中获取信息
        Examination examination = examinationDaoService.selectById(id);
        if (examination == null) {
            throw new CommonException("【考试不存在】 id = "+id);
        }
        return examination;
    }

    //显示路径
    public PageInfo getExams(Integer pageNum, Integer pageSize){
        //查询paper表
        PageInfo page = examinationDaoService.select(pageNum,pageSize);
        return page;
    }

    //设置路径

    /**
     * 设置文件夹路径 type=0_题目 type=1_参考答案 type=2_错误答案 type=3_表格
     */
    public void setDir(Long id,Integer type, String path) throws CommonException {
        //从考试表中获取信息
        Examination examination = examinationDaoService.selectById(id);
        if (examination == null) {
            throw new CommonException("【考试不存在】 id = "+id);
        }
        Examination pojo = new Examination();
        pojo.setId(examination.getId());
        //TODO 检验格式
        switch (type){
            case 0:
                pojo.setExamDir(path);
                break;
            case 1:
                pojo.setReferenceDir(path);
                break;
            case 2:
                pojo.setWrongansDir(path);
                break;
            case 3:
                pojo.setExelDir(path);
                break;
            case 4:
                pojo.setReportDir(path);
                break;
            case 5:
                pojo.setReportsDir(path);
                break;
            case 6:
                pojo.setReportDirThree(path);
                break;
            default:
                throw new  CommonException(CodeMsg.NO_SUCH_TYPE);
        }
        examinationDaoService.update(pojo);
    }



    public void uploadFile(Integer type, MultipartFile file,String homedir) throws CommonException, IOException {
        //todo  校验参数
        switch (type){
            case 0:
                break;
            case 1:
                break;
            case 2:
                break;
            case 3: //表格上传 处理为数据库文件
                //校验是不是exel
                homedirThreadLocal.set(homedir);
                readExel(file);
                break;
            default:
                throw new  CommonException(CodeMsg.NO_SUCH_TYPE);
        }

    }

    //解析exel
    private void readExel(MultipartFile file) throws CommonException, IOException {
        final String fileName = file.getOriginalFilename();
        if (StringUtils.isEmpty(fileName)) {
            throw new  CommonException(CodeMsg.ERROR_FILE_NAME);
        }
        boolean noneMatch = MemeryRoom.exelSuffs.stream().noneMatch(suff -> fileName.endsWith(suff));
        if (noneMatch) {
            throw new  CommonException(CodeMsg.NOT_EXEL);
        }
        readExcel(file);


    }



    public void readExcel(MultipartFile file) throws IOException {
        EasyExcel.read(file.getInputStream(), new NoModelDataListener(excelDaoService)).sheet().headRowNumber(0).doRead();
    }

    //生成总报告
    public String generatReport(Long id) throws IOException {
        //从考试表中获取信息
        Examination examination = examinationDaoService.selectById(id);
        if (examination == null) {
            throw new CommonException("【考试不存在】 id = "+id);
        }
        Long paperId = examination.getPaperId();
        ExamPaper examPaper = examPaperDaoService.selectById(paperId);
        List<WrongAnswer> wrongAnswers = wrongAnswerDaoService.selectByExamId(id);
        //按学生姓名组合
        Map<String, List<WrongAnswer>> collect = wrongAnswers.stream().collect(Collectors.groupingBy(WrongAnswer::getStudentName));

        WordCore wordCore = new WordCore();
        wordCore.setCreated(new Date());
        wordCore.setModified(new Date());
        wordCore.setDescription(examPaper.getTile());
        wordCore.setTitle(examPaper.getTile());
        wordCore.setSubject("");
        wordCore.setCreator("智慧错题本");
        WordPaper wordPaper = new WordPaper(210,297,15,15,15,15,8,8,false);
        WordGo wordGo = new WordGo(wordCore,wordPaper);

        int j = 0;
        int k = 0;
        for (Map.Entry<String, List<WrongAnswer>> entry : collect.entrySet()) {
            List<WrongAnswer> wrongAnswerList = entry.getValue().stream().sorted(Comparator.comparing(a->Integer.valueOf(a.getSubjectId()))).collect(Collectors.toList());

            if (j++!=0) {
                wordGo.newPage();
            }
            wordGo.add( examination.getClassName() +"班_"+entry.getKey()+"_"+examPaper.getTile()+"_错题集_题目\n","font-size:五号; text-align:center; text-decoration:thick");
            for (WrongAnswer wrongAnswer : wrongAnswerList) {
                //标题
                wordGo.addLine("","new-line:true; font-size:五号; font-width: bold; font-family:宋体;font-style:black");
                //题目图片
                ImageLengthDTO imageLengthDTO = dealWithPic(getPicUri(examination.getExamDir() + wrongAnswer.getSubject()));
                wordGo.addImg(getPicUri(examination.getExamDir()+wrongAnswer.getSubject())," new-line:true; width : "+imageLengthDTO.getWidth()+" px; height :"+imageLengthDTO.getHeight()+" px ");

            }

            if (++k!=0) {
                wordGo.newPage();
            }
            wordGo.add( examination.getClassName() +"班_"+entry.getKey()+"_"+examPaper.getTile()+"_错题集_答案\n","font-size:五号; text-align:center; text-decoration:thick");
            for (WrongAnswer wrongAnswer : wrongAnswerList) {

                //标题
                wordGo.addLine("","new-line:true; font-size:五号; font-width: bold; font-family:宋体;font-style:black");
                //参考答案图片
                ImageLengthDTO imageLengthDTO = dealWithPic(getPicUri(examination.getReferenceDir()+wrongAnswer.getSubject()));
                wordGo.addImg(getPicUri(examination.getReferenceDir()+wrongAnswer.getSubject())," new-line:true; width : "+imageLengthDTO.getWidth()+" px; height :"+imageLengthDTO.getHeight()+" px ");
            }
        }

        //页眉
        PaperOut header = new PaperOut();
        header.addText(examination.getClassName() +"班_"+examPaper.getTile());
        header.addCss("font-size: 10; text-align:center");
        wordGo.addHead(header);
        //页脚
        PaperOut foot = new PaperOut();
        foot.addText("第");
        foot.addPage();
        foot.addText("页");
        foot.addCss("font-size: 10; text-align:center");
        wordGo.addFoot(foot);

        //最后生成即可，参数是生成目录，必须带文件名且以.docx结尾
        String reoprt = examination.getReportDir() + examination.getClassName() +"班_"+examPaper.getTile() + ".docx";
        try {
            wordGo.create(reoprt);
        } catch (Exception e) {
            throw e;
        }
        return reoprt;
    }

    private void addPage(boolean isSub,Map<String, List<WrongAnswer>> collect, WordGo wordGo, int i, List<WrongAnswer> wrongAnswerList, int j) {

        if (!((j == wrongAnswerList.size()) && i == collect.entrySet().size())|| isSub) {

            //加空白頁
            if (j == wrongAnswerList.size()&&( j%6 == 1 || j%6 == 2)) {
                wordGo.newPage();
                wordGo.newPage();
            }
            if (j == wrongAnswerList.size()&& (j%6 == 3 || j%6 == 4 ||j%6 == 5)) {
                wordGo.newPage();
            }
            if (j < wrongAnswerList.size() && j%3 == 0) {
                wordGo.newPage();
            }

        }
    }

    private String getPicUri(String filePath) {
        for (String picFileSuffix : PicFileSuffixS) {
            File file = new File(filePath+picFileSuffix);
            if (file.exists()) {
                return filePath+picFileSuffix;
            }
        }

        throw new CommonException("【文件 "+filePath+"  不存在或者图片格式不正确】");
    }

    //生成每个学生的报告
    public String generatReports(Long id) throws IOException {
        WordPaper wordPaper = new WordPaper(210,297,15,15,15,15,8,8,false);
        //从考试表中获取信息
        Examination examination = examinationDaoService.selectById(id);
        if (examination == null) {
            throw new CommonException("【考试不存在】 id = "+id);
        }
        Long paperId = examination.getPaperId();
        ExamPaper examPaper = examPaperDaoService.selectById(paperId);
        List<WrongAnswer> wrongAnswers = wrongAnswerDaoService.selectByExamId(id);
        //按学生姓名组合
        Map<String, List<WrongAnswer>> collect = wrongAnswers.stream().collect(Collectors.groupingBy(WrongAnswer::getStudentName));
        for (Map.Entry<String, List<WrongAnswer>> entry : collect.entrySet()) {
            WordCore wordCore = new WordCore();
            wordCore.setCreated(new Date());
            wordCore.setModified(new Date());
            wordCore.setDescription(examPaper.getTile());
            wordCore.setTitle(examPaper.getTile());
            wordCore.setSubject("");
            wordCore.setCreator("智慧错题本");
            WordGo wordGo = new WordGo(wordCore,wordPaper);
            //排序
            List<WrongAnswer> wrongAnswerList = entry.getValue().stream().sorted(Comparator.comparing(a-> Integer.parseInt(a.getSubjectId()))).collect(Collectors.toList());

                wordGo.addLine("题目部分:","new-line:true; font-size:五号; font-width: bold; font-family:宋体;font-style:black");
                for (WrongAnswer wrongAnswer : wrongAnswerList) {

                    //标题
                    wordGo.addLine("","new-line:true; font-size:四号; font-width: bold; font-family:宋体;font-style:black");
                    //题目图片
                    ImageLengthDTO imageLengthDTO = dealWithPic(getPicUri(examination.getExamDir() + wrongAnswer.getSubject()));
                    wordGo.addImg(getPicUri(examination.getExamDir()+wrongAnswer.getSubject())," new-line:true; width : "+imageLengthDTO.getWidth()+" px; height :"+imageLengthDTO.getHeight()+" px ");

                }

                wordGo.newPage();
                wordGo.addLine("答案部分:","new-line:true; font-size:四号; font-width: bold; font-family:宋体;font-style:black");
                for (WrongAnswer wrongAnswer : wrongAnswerList) {

                    //标题
                    wordGo.addLine("","new-line:true; font-size:五号; font-width: bold; font-family:宋体;font-style:black");
                    //参考答案图片
                    ImageLengthDTO imageLengthDTO = dealWithPic(getPicUri(examination.getReferenceDir() + wrongAnswer.getSubject()));
                    wordGo.addImg(getPicUri(examination.getReferenceDir()+wrongAnswer.getSubject())," new-line:true; width : "+imageLengthDTO.getWidth()+" px; height :"+imageLengthDTO.getHeight()+" px ");

                }

            //页眉页脚
            PaperOut header = new PaperOut();
            header.addText(examination.getClassName() +"班_"+entry.getKey()+"_"+examPaper.getTile());
            header.addCss("font-size: 10; text-align:center");
            wordGo.addHead(header);
            PaperOut foot = new PaperOut();
            foot.addText("第");
            foot.addPage();
            foot.addText("页");
            header.addCss("font-size: 10; text-align:center");
            wordGo.addFoot(foot);

            //最后生成即可，参数是生成目录，必须带文件名且以.docx结尾
            String reoprt = examination.getReportsDir() + examination.getClassName() +"班_"+entry.getKey()+"_"+examPaper.getTile() + ".docx";
            try {
                wordGo.create(reoprt);
            } catch (Exception e) {
                throw e;
            }
        }

        return examination.getReportsDir();
    }

    static String[] PicFileSuffixS = {".png",".jpg",".jpeg"};

    public void deleteExam(Long id) {
        excelDaoService.deleteExam(id);
    }

    private ImageLengthDTO dealWithPic(String fileDir) throws IOException {
        float defaultWith = 700;
        float defaultHeight = 500f;
        ImageLengthDTO imageLengthDTO = new ImageLengthDTO();
        // 读取图片
        BufferedImage bufImage = ImageIO.read(new File(fileDir));

        // 获取图片的宽高
        final int iWidth = bufImage.getWidth();
        final int iHeight = bufImage.getHeight();

        //如果图片比400宽
        if (iWidth/defaultWith > iHeight/defaultHeight && iWidth/defaultWith >=1) {
            imageLengthDTO.setWidth(defaultWith);
            imageLengthDTO.setHeight(iHeight*defaultWith/iWidth);
        }
        else if (iWidth/defaultWith < iHeight/defaultHeight && iHeight/defaultHeight >=1) {
            imageLengthDTO.setWidth(defaultWith*defaultHeight/iHeight);
            imageLengthDTO.setHeight(defaultHeight);
        }
        else {
            imageLengthDTO.setWidth(iWidth);
            imageLengthDTO.setHeight(iHeight);
        }
        return imageLengthDTO;
    }

    /**
     * 所有同学的题目生成后，再生成所有同学的答案
     * @param id
     * @return
     */
    public String generatReportThree(Long id) throws IOException {
        //从考试表中获取信息
        Examination examination = examinationDaoService.selectById(id);
        if (examination == null) {
            throw new CommonException("【考试不存在】 id = "+id);
        }
        Long paperId = examination.getPaperId();
        ExamPaper examPaper = examPaperDaoService.selectById(paperId);
        List<WrongAnswer> wrongAnswers = wrongAnswerDaoService.selectByExamId(id);
        //按学生姓名组合
        Map<String, List<WrongAnswer>> collect = wrongAnswers.stream().collect(Collectors.groupingBy(WrongAnswer::getStudentName));

        WordCore wordCore = new WordCore();
        wordCore.setCreated(new Date());
        wordCore.setModified(new Date());
        wordCore.setDescription(examPaper.getTile());
        wordCore.setTitle(examPaper.getTile());
        wordCore.setSubject("");
        wordCore.setCreator("智慧错题本");

        WordPaper wordPaper = new WordPaper(210,297,15,15,15,15,8,8,false);
        WordGo wordGo = new WordGo(wordCore,wordPaper);

        int j = 0;
        for (Map.Entry<String, List<WrongAnswer>> entry : collect.entrySet()) {
            List<WrongAnswer> wrongAnswerList = entry.getValue().stream().sorted(Comparator.comparing(a->Integer.valueOf(a.getSubjectId()))).collect(Collectors.toList());
            if (j++!=0) {
                wordGo.newPage();
            }
            wordGo.add( examination.getClassName() +"班_"+entry.getKey()+"_"+examPaper.getTile()+"_错题集_题目\n","font-size:五号; text-align:center; text-decoration:thick");
            for (WrongAnswer wrongAnswer : wrongAnswerList) {
                //标题
                wordGo.addLine("","new-line:true; font-size:五号; font-width: bold; font-family:宋体;font-style:black");
                //题目图片
                ImageLengthDTO imageLengthDTO = dealWithPic(getPicUri(examination.getExamDir() + wrongAnswer.getSubject()));
                wordGo.addImg(getPicUri(examination.getExamDir()+wrongAnswer.getSubject())," new-line:true; width : "+imageLengthDTO.getWidth()+" px; height :"+imageLengthDTO.getHeight()+" px ");

            }

        }
        int k = 0;
        for (Map.Entry<String, List<WrongAnswer>> entry : collect.entrySet()) {
            List<WrongAnswer> wrongAnswerList = entry.getValue().stream().sorted(Comparator.comparing(a->Integer.valueOf(a.getSubjectId()))).collect(Collectors.toList());
            if (++k!=0) {
                wordGo.newPage();
            }
            wordGo.add( examination.getClassName() +"班_"+entry.getKey()+"_"+examPaper.getTile()+"_错题集_答案\n","font-size:五号; text-align:center; text-decoration:thick");

            for (WrongAnswer wrongAnswer : wrongAnswerList) {
                //标题
                wordGo.addLine("","new-line:true; font-size:五号; font-width: bold; font-family:宋体;font-style:black");

                //参考答案图片
                ImageLengthDTO imageLengthDTO = dealWithPic(getPicUri(examination.getReferenceDir()+wrongAnswer.getSubject()));
                wordGo.addImg(getPicUri(examination.getReferenceDir()+wrongAnswer.getSubject())," new-line:true; width : "+imageLengthDTO.getWidth()+" px; height :"+imageLengthDTO.getHeight()+" px ");

            }
        }



        //页眉
        PaperOut header = new PaperOut();
        header.addText(examination.getClassName() +"班_"+examPaper.getTile());
        header.addCss("font-size: 10; text-align:center");
        wordGo.addHead(header);
        //页脚
        PaperOut foot = new PaperOut();
        foot.addText("第");
        foot.addPage();
        foot.addText("页");
        foot.addCss("font-size: 10; text-align:center");
        wordGo.addFoot(foot);

        //最后生成即可，参数是生成目录，必须带文件名且以.docx结尾
        String reoprt = examination.getReportDirThree() + examination.getClassName() +"班_"+examPaper.getTile() + "汇总错题集.docx";
        try {
            wordGo.create(reoprt);
        } catch (Exception e) {
            throw e;
        }
        return reoprt;
    }
}
